package com.TetrisII.control;

import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import java.util.Timer;
import java.util.TimerTask;

import javax.swing.JOptionPane;

import com.TetrisII.entities.DirectionEnum;
import com.TetrisII.entities.Ground;
import com.TetrisII.entities.Shape;
import com.TetrisII.entities.ShapeFactory;
import com.TetrisII.extra.model.BoomShape;

import com.TetrisII.views.GamePanel;
import com.TetrisII.views.MainFrame;
import com.TetrisII.views.PreviewPanel;

/**
 * C层控制，控制View显示组件层和M层数据
 * 
 * @author Administrator
 *
 */
public class ShapeControllers extends KeyAdapter {
	private Shape shape;// 接收工厂方块
	private Ground ground;// 控制背景数组
	private GamePanel gamePanel;// 控制游戏面板
	private PreviewPanel preview;// 控制预览面板
	private ShapeFactory shapeFactory;// 控制工厂输出
	private MainFrame mainFrame;// 主屏幕控制
	private boolean pause;// 是否暂停
	private boolean bingo;// 底层是否开始上涨
	private int countShape;// 计算掉落方块，没5个升一次
	private boolean produceBoom;// 是否产生方块
	private boolean frameContinue;// 让炸弹只产生一次

	private Timer time;// 定时器
	private int speed;// 速度

	/**
	 * 构造方法初始化
	 * 
	 * @param gamePanel
	 *            添加游戏面板
	 * @param shapeFactory
	 *            添加工厂
	 * @param ground
	 *            添加背景数组
	 */
	public ShapeControllers(GamePanel gamePanel, ShapeFactory shapeFactory, Ground ground) {
		// TODO Auto-generated constructor stub
		this.gamePanel = gamePanel;
		this.shapeFactory = shapeFactory;
		this.ground = ground;
		this.shape = shapeFactory.getShape();

		speed = 800;
		pause = true;
		produceBoom = true;
		time = new Timer();
		time.schedule(new AutoDown(), 100, speed);

	}

	/**
	 * 下落的速度等级
	 * 
	 * @param level
	 *            为输入的难度
	 */
	public void setShapeSpeed(int speed) {

		time.cancel();
		time = new Timer();
		this.speed = speed;
		time.schedule(new AutoDown(), 100, speed);

	}

	/**
	 * 级别设置
	 * 
	 * @param level 输入1、2、3对应的等级，7、9、11种方块
	 *  
	 */
	public void setShapeLevel(int level) {
		shapeFactory.levelShape(level);
	}

	/**
	 * 底层上涨
	 */
	public void upGround() {
		countShape++;
		if (countShape % 5 == 0) {
			ground.upToGround();
		}
	}

	/**
	 * 键盘监听
	 */

	public void keyPressed(KeyEvent e) {
		// // TODO Auto-generated method stub
		if (pause == false) {
			if (e.getKeyCode() == KeyEvent.VK_RIGHT) {
				if (ground.isMoveable(shape, DirectionEnum.RIGHT))
					shape.moveRight();
			}
			if (e.getKeyCode() == KeyEvent.VK_LEFT) {
				if (ground.isMoveable(shape, DirectionEnum.LEFT))
					shape.moveLeft();
			}
			if (e.getKeyCode() == KeyEvent.VK_UP)

			{

				if (ground.isMoveable(shape, DirectionEnum.CHANGE))
					shape.changeBody();
			}
			if (e.getKeyCode() == KeyEvent.VK_DOWN) {
				if (ground.isMoveable(shape, DirectionEnum.DOWN)) {
					shape.moveDown();
				}
			}
			if (e.getKeyCode() == KeyEvent.VK_SPACE) {
				oneKeyToLow();

			}
			if (e.getKeyCode() == KeyEvent.VK_P) {
				pauseGame();
			}

		}
		if (e.getKeyCode() == KeyEvent.VK_R) {
			continueGame();
			;
		}
	}

	/**
	 * 暂停游戏
	 */
	public void pauseGame() {
		pause = true;
	}

	/**
	 * 继续游戏
	 */
	public void continueGame() {
		pause = false;

	}

	/**
	 * 开始游戏
	 */
	public void beginGame() {
		gamePanel.beginGame(shape, ground);
	}

	/**
	 * 重新开始
	 */

	public void restartGame() {
		pause = false;
		shape = shapeFactory.getShape();
		gamePanel.beginGame(shape, ground);
		preview.newShape();
		ground.initGround();
	}

	/**
	 * 整百分时出现一个炸弹
	 * 
	 * @param goals
	 */
	public void getBoom(int goals) {
		int boom = goals % 100;
		if (produceBoom) {
			if (goals > 0 && boom == 0) {
				shape = new BoomShape();
				produceBoom = false;
			}
		}
		if (boom != 0) {
			produceBoom = true;
		}
	}

	/**
	 * 定时器，方块自动下落线程，产生新方块等
	 * 
	 * @author Administrator
	 *
	 */
	public class AutoDown extends TimerTask {
		public void run() {
			if (ground.isMoveable(shape, DirectionEnum.DOWN)) {
				if (pause == false) {
					shape.moveDown();

				}

			} else {
				// 不能下落时产生新方块
				if (ground.gameOver() == false) {
					if (shape instanceof BoomShape) {
						ground.bomb();
					} else {
						ground.accept(shape);
						ground.delectLine();
					} // 每加进来判断消行
					if (bingo) {

						upGround();
					}
					shape = preview.preShape();
					getBoom(ground.getGoals());
					gamePanel.beginGame(shape, ground);
					preview.newShape();
				} else {
					int n = JOptionPane.showConfirmDialog(null, "您失败了，再来一局？", "游戏结束", JOptionPane.YES_NO_OPTION);
					if (n == JOptionPane.YES_OPTION) {
						restartGame();
					} else if (n == JOptionPane.NO_OPTION) {
						System.exit(0);
					}
				}

			}

		}
	}

	/**
	 * 一键下落
	 */
	public void oneKeyToLow() {
		while (ground.isMoveable(shape, DirectionEnum.DOWN)) {
			shape.moveDown();
		}
	}

	/**
	 * 加入预览面板控制
	 * 
	 * @param preview
	 */
	public void setPreview(PreviewPanel preview) {
		this.preview = preview;
	}

	/**
	 * 添加主屏幕控制
	 * 
	 * @param mainFrame
	 */
	public void setMianFrame(MainFrame mainFrame) {
		this.mainFrame = mainFrame;
	}

	/**
	 * 游戏面板
	 * 
	 * @return 返回面板对象
	 */
	public GamePanel getGamePanel() {
		return gamePanel;
	}

	/**
	 * 设置游戏面板
	 * 
	 * @param gamePanel
	 */
	public void setGamePanel(GamePanel gamePanel) {
		this.gamePanel = gamePanel;
	}

	/**
	 * 获得工厂
	 * 
	 * @return
	 */
	public ShapeFactory getShapeFactory() {
		return shapeFactory;
	}

	/**
	 * 设置工厂对象
	 * 
	 * @param shapeFactory
	 */
	public void setShapeFactory(ShapeFactory shapeFactory) {
		this.shapeFactory = shapeFactory;
	}

	/**
	 * 获得主屏幕
	 * 
	 * @return
	 */
	public MainFrame getMainFrame() {
		return mainFrame;
	}

	/**
	 * 设置主屏幕
	 * 
	 * @param mainFrame
	 */
	public void setMainFrame(MainFrame mainFrame) {
		this.mainFrame = mainFrame;
	}

	/**
	 * 底层是否上涨
	 * 
	 * @return
	 */
	public boolean isBingo() {
		return bingo;
	}

	/**
	 * 设置底层是否上涨
	 * 
	 * @param bingo
	 */
	public void setBingo(boolean bingo) {
		this.bingo = bingo;
	}

	/**
	 * 获得计时器线程
	 * 
	 * @return
	 */
	public Timer getTime() {
		return time;
	}

	/**
	 * 设置计时器线程
	 * 
	 * @param time
	 */
	public void setTime(Timer time) {
		this.time = time;
	}

	/**
	 * 获得方块下落速度
	 * 
	 * @return
	 */
	public int getSpeed() {
		return speed;
	}

	/**
	 * 设置方块下落速度，单位为毫秒mills
	 * 
	 * @param speed
	 */
	public void setSpeed(int speed) {
		this.speed = speed;
	}

	/**
	 * 获得预览面板
	 * 
	 * @return
	 */
	public PreviewPanel getPreview() {
		return preview;
	}

	/**
	 * 获得控制方块
	 * 
	 * @return
	 */
	public Shape getShape() {
		return shape;
	}

	/**
	 * 设置控制方块
	 * 
	 * @param shape
	 */
	public void setShape(Shape shape) {
		this.shape = shape;
	}

	/**
	 * 获得控制背景数组
	 * 
	 * @return
	 */
	public Ground getGround() {
		return ground;
	}

	/**
	 * 设置控制背景数组
	 * 
	 * @param ground
	 */
	public void setGround(Ground ground) {
		this.ground = ground;
	}

	/**
	 * 获得是否暂停
	 * 
	 * @return
	 */
	public boolean isPause() {
		return pause;
	}

	/**
	 * 设置是否暂停
	 * 
	 * @param pause
	 */
	public void setPause(boolean pause) {
		this.pause = pause;
	}

	/**
	 * 获得屏幕是否已经停止
	 * 
	 * @return
	 */
	public boolean isFrameContinue() {
		return frameContinue;
	}

	/**
	 * 设置屏幕是否已经停止
	 * 
	 * @param frameContinue
	 */
	public void setFrameContinue(boolean frameContinue) {
		this.frameContinue = frameContinue;
	}

}
